package com.bkgy.controller.repTechFit.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.controller.repTechFit.entity.RepTechFit;
import com.bkgy.controller.repTechFit.entity.pdo.TcmProcessDatasJudge;
import com.bkgy.controller.repTechFit.mapper.IRepTechFitMapper;
import com.bkgy.controller.repTechFit.service.IRepTechFitService;
import com.bkgy.controller.technology.entity.dto.FailReasonNum;
import com.bkgy.controller.technology.entity.dto.TechFailBarRes;
import com.bkgy.sys.common.constant.CommonConstant;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
@RequiredArgsConstructor
public class RepTechFitServiceImpl extends ServiceImpl<IRepTechFitMapper, RepTechFit> implements IRepTechFitService {
    private final IRepTechFitMapper mapper;

    @Override
    public ResultData<String> buildSucRateJob(Date d1) {
        String beginDate = DateUtil.getDateToString(d1, "yyyyMMdd");
        String endDate = DateUtil.getDateToString(DateUtil.getNextDayZero(d1), "yyyyMMdd");
        List<TcmProcessDatasJudge> list = mapper.selectProcessData(beginDate, endDate);
        //按班组分组数据
        Map<String, List<TcmProcessDatasJudge>> crewMapData = new HashMap<>();
        for (TcmProcessDatasJudge p : list) {
            String crew = p.getCrew();
            if (!crewMapData.containsKey(crew)) {
                List<TcmProcessDatasJudge> l = new ArrayList<>();
                l.add(p);
                crewMapData.put(crew, l);
            } else {
                crewMapData.get(crew).add(p);
            }
        }

        String[] acidArr = new String[]{"TcmProcessSpeed", "TcmTank1Temp", "TcmTank2Temp", "TcmTank3Temp", "Acid1", "FeContent1", "Acid3", "FeContent3", "TcmRinsePh", "TcmDryTemp"};
        //TODO 乳化液1#箱温度，乳化液3#箱温度，5#乳化液喷射梁压力 客户要求不统计
        String[] pressArr = new String[]{"RollSpeed"/*, "TcmTank1EmuTemp"*/, "TcmTank2EmuTemp", /*"TcmTank3EmuTemp", */"ImpureOil", "Tcm1RuPressure", "Tcm2RuPressure", "Tcm3RuPressure", "Tcm4RuPressure"/*, "Tcm5RuPressure"*/, "BandFslv"};
        List<RepTechFit> resList = new ArrayList<>();
        for (Map.Entry<String, List<TcmProcessDatasJudge>> entry : crewMapData.entrySet()) {
            RepTechFit crewRep = new RepTechFit();
            int hege = 0, rukou = 0, suanxi = 0, zhazhi = 0;

            //一个班组的数据
            List<TcmProcessDatasJudge> ps = entry.getValue();
            for (TcmProcessDatasJudge p : ps) {
                boolean hegeFlag = true;

                //入口段
                if (p.getTcmTlElongJudge() == 1) {
                    Integer oldV = crewRep.getTcmTlElongCount();
                    crewRep.setTcmTlElongCount(oldV == null ? 1 : oldV + 1);
                    rukou++;
                    hegeFlag = false;
                }
                //酸洗段
                boolean suanxiFlag = false;//酸洗段是否有问题
                for (String col : acidArr) {
                    try {
                        Integer v = (Integer) p.getClass().getMethod("get" + col + "Judge").invoke(p);
                        if (v != null && v == 1) {
                            Integer oldV = (Integer) crewRep.getClass().getMethod("get" + col + "Count").invoke(crewRep);
                            crewRep.getClass().getMethod("set" + col + "Count", Integer.class).invoke(crewRep, oldV == null ? 1 : oldV + 1);
                            suanxiFlag = true;
                            hegeFlag = false;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (suanxiFlag) suanxi++;

                //轧制段
                boolean zhazhiFlag = false;
                for (String col : pressArr) {
                    try {
                        Integer v = (Integer) p.getClass().getMethod("get" + col + "Judge").invoke(p);
                        if (v != null && v == 1) {
                            Integer oldV = (Integer) crewRep.getClass().getMethod("get" + col + "Count").invoke(crewRep);
                            crewRep.getClass().getMethod("set" + col + "Count", Integer.class).invoke(crewRep, oldV == null ? 1 : oldV + 1);
                            zhazhiFlag = true;
                            hegeFlag = false;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (zhazhiFlag) zhazhi++;

                if (hegeFlag) hege++;
            }

            crewRep.setShijian(beginDate);
            crewRep.setCrew(entry.getKey());
            crewRep.setLineName("TCM2280");
            crewRep.setZongjuans(ps.size());
            crewRep.setHege(hege);
            crewRep.setRukoud(rukou);
            crewRep.setSuanxi(suanxi);
            crewRep.setZhazhi(zhazhi);

            resList.add(crewRep);
        }
        if (resList.size() > 0) saveBatch(resList);

        return ResultData.ResultDataSuccess("SUCCESS");
    }

    @Override
    public List<RepTechFit> selectCrewThisMonth(String startDate, String endDate) {
        if (StringUtils.isEmpty(startDate)) {
            startDate = DateUtil.thisMonthFirstDay("yyyyMMdd");
        }
        return mapper.selectCrewThisMonth(startDate, endDate);
    }

    @Override
    public RepTechFit selectThisMonth(String startDate, String endDate) {
        if (StringUtils.isEmpty(startDate)) {
            startDate = DateUtil.thisMonthFirstDay("yyyyMMdd");
        }
        return mapper.selectThisMonth(startDate, endDate);
    }

    @Override
    public ResultData<TechFailBarRes> techFailBar(String startDate, String endDate) {
        LambdaQueryWrapper<RepTechFit> w = new LambdaQueryWrapper<>();
        w.ge(RepTechFit::getShijian, startDate).le(RepTechFit::getShijian, endDate);
        List<RepTechFit> list = list(w);
        //分班归类
        Map<String, List<RepTechFit>> crewMap = new HashMap<>();
        for (RepTechFit f : list) {
            if (!crewMap.containsKey(f.getCrew())) {
                List<RepTechFit> l = new ArrayList<>();
                l.add(f);
                crewMap.put(f.getCrew(), l);
            } else {
                crewMap.get(f.getCrew()).add(f);
            }
        }

        //分班组统计
        List<TechFailBarRes> resList = new ArrayList<>();
        for (Map.Entry<String, List<RepTechFit>> entry : crewMap.entrySet()) {
            List<RepTechFit> crewList = entry.getValue();
            int lajiao = 0, honggan = 0, ruhua1 = 0, ruhua2 = 0, ruhua3 = 0;
            int total = 0, hege = 0;
            for (RepTechFit f : crewList) {
                total += f.getZongjuans();
                hege += f.getHege();
                lajiao += f.getTcmTlElongCount();
                honggan += f.getTcmDryTempCount();
                ruhua1 += f.getTcmTank1EmuTempCount();
                ruhua2 += f.getTcmTank2EmuTempCount();
                ruhua3 += f.getTcmTank3EmuTempCount();
            }

            List<FailReasonNum> reasons = new ArrayList<>();
            reasons.add(new FailReasonNum("拉矫机延伸率", lajiao));
            reasons.add(new FailReasonNum("烘干机温度", honggan));
            reasons.add(new FailReasonNum("乳化液1#箱温度", ruhua1));
            reasons.add(new FailReasonNum("乳化液2#箱温度", ruhua2));
            reasons.add(new FailReasonNum("乳化液3#箱温度", ruhua3));
            Collections.sort(reasons);

            TechFailBarRes res = new TechFailBarRes();
            res.setCrew(CommonConstant.crewMap.get(entry.getKey()));
            res.setTotal(total);
            res.setFailNum(total - hege);
            res.setReasons(reasons);

            resList.add(res);
        }

        return ResultData.ResultDataSuccess(resList, resList.size());
    }

    @Override
    public ResultData<JSONObject> techSucRate(String startDate, String endDate) {
        if (StringUtils.isEmpty(startDate)) {
            //加载7天的数据
            int day = 6;
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.add(Calendar.DAY_OF_MONTH, -day);

            startDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMdd");
        }
        LambdaQueryWrapper<RepTechFit> w = new LambdaQueryWrapper<>();
        w.ge(RepTechFit::getShijian, startDate);
        if (StringUtils.isEmpty(endDate)) {
            w.le(RepTechFit::getShijian, endDate);
        }
        w.orderByAsc(RepTechFit::getShijian);

        List<RepTechFit> list = list(w);
        //按日期分组
        Map<String, List<RepTechFit>> shijianMap = new TreeMap<>();
        for (RepTechFit f : list) {
            if (!shijianMap.containsKey(f.getShijian())) {
                List<RepTechFit> l = new ArrayList<>();
                l.add(f);
                shijianMap.put(f.getShijian(), l);
            } else {
                shijianMap.get(f.getShijian()).add(f);
            }
        }
        List<String> xList = new ArrayList<>();
        List<BigDecimal> yList = new ArrayList<>();
        List<BigDecimal> rukouList = new ArrayList<>();
        List<BigDecimal> suanxiList = new ArrayList<>();
        List<BigDecimal> zhazhiList = new ArrayList<>();
        for (Map.Entry<String, List<RepTechFit>> entry : shijianMap.entrySet()) {
            Date d = DateUtil.getStringToDate("yyyyMMdd", entry.getKey());
            xList.add(DateUtil.getDateToString(d, "yyyy-MM-dd"));
            int total = 0, hege = 0, rukou = 0, suanxi = 0, zhazhi = 0;
            List<RepTechFit> shijianList = entry.getValue();
            for (RepTechFit f : shijianList) {
                total += f.getZongjuans();
                hege += f.getHege();
                rukou += f.getRukoud();
                suanxi += f.getSuanxi();
                zhazhi += f.getZhazhi();
            }
            yList.add(BigDecimal.valueOf(hege).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
            rukouList.add(BigDecimal.valueOf(total - rukou).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
            suanxiList.add(BigDecimal.valueOf(total - suanxi).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
            zhazhiList.add(BigDecimal.valueOf(total - zhazhi).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
        }

        JSONObject obj = new JSONObject();
        obj.put("x", xList);
        obj.put("y", yList);
        obj.put("rukouY", rukouList);
        obj.put("suanxiY", suanxiList);
        obj.put("zhazhiY", zhazhiList);

        return ResultData.ResultDataSuccess(obj);
    }

    @Override
    public ResultData<JSONObject> techFailLine(String dateType) {
        JSONObject obj = new JSONObject();
        List<String> xList = new ArrayList<>();
        List<BigDecimal> yList = new ArrayList<>();

        if ("week".equals(dateType)) {
            //按周统计最近4周的不合格率
            String[] weekRankArr = DateUtil.getWeekRankArr(4);
            for (String rank : weekRankArr) {
                xList.add(rank);
            }
            Calendar cal = Calendar.getInstance();
            cal.setTime(DateUtil.getCurrentZero(new Date()));
            cal.setFirstDayOfWeek(Calendar.MONDAY);
            cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            cal.add(Calendar.DAY_OF_MONTH, -7 * 3);//前3周
            String beginDate = DateUtil.getDateToString(cal.getTime(), "yyyyMMdd");
            LambdaQueryWrapper<RepTechFit> w = new LambdaQueryWrapper<>();
            w.ge(RepTechFit::getShijian, beginDate);
            List<RepTechFit> list = list(w);
            int total = 0, hege = 0;
            long days = 24 * 60 * 60 * 1000;
            for (RepTechFit f : list) {
                Date d = DateUtil.getStringToDate("yyyyMMdd", f.getShijian());
                if ((d.getTime() - cal.getTime().getTime()) / days > 6) {
                    if (total > 0) {
                        yList.add(BigDecimal.valueOf(total - hege).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
                    } else {
                        yList.add(BigDecimal.ZERO);
                    }
                    total = f.getZongjuans();
                    hege = f.getHege();
                    cal.setTime(d);
                } else {
                    total += f.getZongjuans();
                    hege += f.getHege();
                }
            }
            if (total > 0) {
                yList.add(BigDecimal.valueOf(total - hege).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
            } else {
                yList.add(BigDecimal.ZERO);
            }
        } else if ("month".equals(dateType)) {
            //按月统计不合格率
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            int month1 = cal.get(Calendar.MONTH) + 1;
            cal.add(Calendar.MONTH, -3);
            String beginDate = DateUtil.getDateToString(cal.getTime(), "yyyyMM01");
            LambdaQueryWrapper<RepTechFit> w = new LambdaQueryWrapper<>();
            w.ge(RepTechFit::getShijian, beginDate);
            List<RepTechFit> list = list(w);

            int total = 0, hege = 0;
            int month2 = cal.get(Calendar.MONTH) + 1;
            int i = month2;
            while (i <= month1) {
                xList.add(i + "月");
                i++;
            }

            for (RepTechFit f : list) {
                Date d = DateUtil.getStringToDate("yyyyMMdd", f.getShijian());
                Calendar cal2 = Calendar.getInstance();
                cal2.setTime(d);
                int currentMonth = cal2.get(Calendar.MONTH) + 1;
                if (currentMonth > month2) {
                    if (total > 0) {
                        yList.add(BigDecimal.valueOf(total - hege).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
                    } else {
                        yList.add(BigDecimal.ZERO);
                    }
                    //防止连续月无数据
                    while (month2 + 1 != currentMonth) {
                        yList.add(BigDecimal.ZERO);
                        month2++;
                        if (month2 > 13) break;
                    }
                    total = f.getZongjuans();
                    hege = f.getHege();
                    month2 = currentMonth;
                } else {
                    total += f.getZongjuans();
                    hege += f.getHege();
                }
            }
            if (total > 0) {
                yList.add(BigDecimal.valueOf(total - hege).multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP));
            } else {
                yList.add(BigDecimal.ZERO);
            }
        }
        obj.put("x", xList);
        obj.put("y", yList);
        return ResultData.ResultDataSuccess(obj);
    }
}
